package dynamic.injector;

/*
 * Copyright (c) 2011-2023, baomidou (jobob@qq.com).
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.GlobalConfigUtils;
import dynamic.ibatis.builder.DMapperBuilderAssistant;
import dynamic.metadata.DTableInfo;
import dynamic.metadata.DTableInfoHelper;
import dynamic.metadata.EntityClass;
import dynamic.mybatisplus.core.injector.DAbstractMethod;
import dynamic.mybatisplus.core.toolkit.DGlobalConfigUtils;
import org.apache.ibatis.builder.MapperBuilderAssistant;
import org.apache.ibatis.logging.Log;
import org.apache.ibatis.logging.LogFactory;

import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * SQL 自动注入器
 *
 * @author hubin
 * @since 2018-04-07
 */
public abstract class DAbstractSqlInjector implements DISqlInjector {

    protected final Log logger = LogFactory.getLog(this.getClass());

    @Override
    public void inspectInject(DMapperBuilderAssistant builderAssistant, Class<?> mapperClass, EntityClass modelClass) {

        if (modelClass != null) {
            String className = mapperClass.toString();
            Map<String, Set<EntityClass>> mapperRegistryCache = DGlobalConfigUtils.getMapperRegistryCache(builderAssistant.getConfiguration());
            if (!(mapperRegistryCache.containsKey(className)&&mapperRegistryCache.get(className).contains(modelClass))) {
                DTableInfo tableInfo = DTableInfoHelper.initTableInfo(builderAssistant, modelClass);
                List<DAbstractMethod> methodList = this.getMethodList(mapperClass, tableInfo);
                if (CollectionUtils.isNotEmpty(methodList)) {
                    // 循环注入自定义方法
                    for (DAbstractMethod m : methodList) {
                        m.inject(builderAssistant, mapperClass, modelClass, tableInfo);
                    }
                } else {
                    logger.debug(mapperClass.toString() + ", No effective injection method was found.");
                }
                if(!mapperRegistryCache.containsKey(className)){
                    mapperRegistryCache.put(className,new HashSet<>());
                }
                mapperRegistryCache.get(className).add(modelClass);
            }
        }
    }

    /**
     * <p>
     * 获取 注入的方法
     * </p>
     *
     * @param mapperClass 当前mapper
     * @return 注入的方法集合
     * @since 3.1.2 add  mapperClass
     */
    public abstract List<DAbstractMethod> getMethodList(Class<?> mapperClass, DTableInfo tableInfo);

}

